#include <stdlib.h>
#include <stdio.h>

#include "SDL.h"
#include "SDL_opengl.h"
#include "cairo-rendering.h"

#define WIN_WIDTH 720
#define WIN_HEIGHT 576

#define UNUSED(x) (void)x
#define ColoredVertex(c, v) do{ glColor3fv(c); glVertex3fv(v); }while(0)  
static int angle = 0;  
GLfloat  
    PointA[] = { 0.25f, 0.25f, -0.25f },  
    PointB[] = { 0.25f, -0.25f, -0.25f },  
    PointC[] = { -0.25f, -0.25f, -0.25f },  
    PointD[] = { -0.25f, 0.25f, -0.25f },  
    PointE[] = { 0.25f, 0.25f, 0.25f },  
    PointF[] = { 0.25f, -0.25f, 0.25f },  
    PointG[] = { -0.25f, -0.25f, 0.25f },  
    PointH[] = { -0.25f, 0.25f, 0.25f };  
GLfloat  
    ColorA[] = { 1, 0, 0 },  
    ColorB[] = { 0, 1, 0 },  
    ColorC[] = { 0, 0, 1 },  
    ColorD[] = { 1, 1, 0 },  
    ColorE[] = { 1, 0, 1 },  
    ColorF[] = { 0, 1, 1 },  
    ColorG[] = { 1, 1, 1 },  
    ColorH[] = { 0, 0, 0 };  
void myDisplay(void)  
{  
    static int list = 0;  
	glEnable(GL_CULL_FACE);
    glEnable(GL_DEPTH_TEST);

    if (list == 0)  
    {  
        list = glGenLists(1);  
        glNewList(list, GL_COMPILE);  
          
        // 面1             
        glBegin(GL_POLYGON);           //准备添加面顶点
        ColoredVertex(ColorA, PointA); //添加面的顶点1
        ColoredVertex(ColorE, PointE); //添加面的顶点2
        ColoredVertex(ColorH, PointH); //添加面的顶点3
        ColoredVertex(ColorD, PointD); //添加面的顶点4
        glEnd();                       //结束面顶点的添加
          
        // 面2  
        glBegin(GL_POLYGON);  
        ColoredVertex(ColorD, PointD);  
        ColoredVertex(ColorC, PointC);  
        ColoredVertex(ColorB, PointB);  
        ColoredVertex(ColorA, PointA);  
        glEnd();  
          
        // 面3  
        glBegin(GL_POLYGON);  
        ColoredVertex(ColorA, PointA);  
        ColoredVertex(ColorB, PointB);  
        ColoredVertex(ColorF, PointF);  
        ColoredVertex(ColorE, PointE);  
        glEnd();  
          
        // 面4  
        glBegin(GL_POLYGON);  
        ColoredVertex(ColorF, PointF);  
        ColoredVertex(ColorG, PointG);  
        ColoredVertex(ColorH, PointH);  
        ColoredVertex(ColorE, PointE);  
        glEnd();  
          
        // 面5  
        glBegin(GL_POLYGON);  
        ColoredVertex(ColorF, PointF);  
        ColoredVertex(ColorB, PointB);  
        ColoredVertex(ColorC, PointC);  
        ColoredVertex(ColorG, PointG);  
        glEnd();  

        // 面6  
        glBegin(GL_POLYGON);  
        ColoredVertex(ColorC, PointC);  
        ColoredVertex(ColorD, PointD);  
        ColoredVertex(ColorH, PointH);  
        ColoredVertex(ColorG, PointG);  
        glEnd();  
        glEndList();  
    }  

    // 已经创建了显示列表，在每次绘制正四面体时将调用它  
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
    glPushMatrix();  
    glRotatef(angle++ , 1, 0.5, 0);  
    glCallList(list);  
    glPopMatrix();  
	
	SDL_GL_SwapBuffers();
}  
  

int main(int argc, char **argv)
{
	UNUSED(argc);
	UNUSED(argv);

	int width = WIN_WIDTH;
	int height = WIN_HEIGHT;
	unsigned int texture_id;
	SDL_Surface *surf_window = NULL;
	SDL_Event event;
	int keep_running = 1;
	cairo_surface_t *surf = NULL;
	cairo_t *cr;
	unsigned char *surf_data;


	// init SDL
	if ((SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) == -1))
	{
		printf("Could not initialize SDL: %s.\n", SDL_GetError());
		exit(-1);
	}

	// set window title
	SDL_WM_SetCaption("gl-cairo-simple", NULL);
	// create "GL-context"
	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	surf_window = SDL_SetVideoMode(width, height, 0, SDL_OPENGL | SDL_RESIZABLE);

	// did we get what we want?
	if (!surf_window)
	{
		printf("Couldn't open SDL-window: %s\n", SDL_GetError());
		exit(-2);
	}

	// create cairo-surface/context to act as OpenGL-texture source
	cr = create_cairo_context(width, height, 4, &surf, &surf_data);

	// enter event-loop
	while (keep_running)
	{
		// get event from queue
		SDL_PollEvent(&event);

		switch (event.type)
		{
		// check for user hitting close-window widget
		case SDL_QUIT:
			keep_running = 0;
			break;
		}

		render_curve(cr, width, height);
		myDisplay();
		// try to get a redraw-rate of 50 Hz
		SDL_Delay(20);
	}

	// clear resources before exit
	glDeleteTextures(1, &texture_id);
	free(surf_data);
	cairo_destroy(cr);
	SDL_Quit();

	return 0;
}
